package space.panker916.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import space.panker916.pojo.DiscussPost;
import space.panker916.service.DiscussPostService;
import space.panker916.service.ElasticsearchService;
import space.panker916.service.LikeService;
import space.panker916.utils.RedisKeyUtil;

import static space.panker916.utils.Constants.*;

public class PostScoreRefreshJob extends QuartzJobBean {
    private static final Logger logger = LoggerFactory.getLogger(PostScoreRefreshJob.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DiscussPostService discussPostService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private ElasticsearchService elasticsearchService;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        String postScoreKey = RedisKeyUtil.getPostScoreKey();
        BoundSetOperations operations = redisTemplate.boundSetOps(postScoreKey);

        logger.info("[更新帖子分数的任务开始] 待更新的帖子的数量: " + operations.size());

        while (operations.size() > 0) {
            this.refresh((Integer) operations.pop());
        }

        logger.info("[更新帖子分数的任务结束] 所有帖子更新完毕！");
    }

    // 帖子分数计算公式：log(精华分 + 评论数*10 + 点赞数*2 + 收藏数*2) + (发布时间 - 牛客纪元)
    private void refresh(int postId) {
        DiscussPost discussPost = discussPostService.findDiscussPostById(postId);

        if (discussPost == null || discussPost.getStatus() == 2) {
            logger.error("id 为 " + postId + " 的帖子不存在！");
        }

        // 是否精华
        int wonderfulScore = discussPost.getStatus() == 1 ? WONDERFUL_SCORE : 0;
        // 评论数量
        int commentCount = discussPost.getCommentCount();
        // 点赞数量
        long likeCount = likeService.findEntityLikeCount(ENTITY_TYPE_POST, discussPost.getId());

        // 计算权重（注意：因为这个社区 demo 没有做收藏帖子的功能，所以收藏帖子的分数先不进行计算）
        double w = (wonderfulScore + commentCount * 10 + likeCount * 2);
        // 最终分数 = 帖子权重 + 距离天数
        double score = Math.log10(Math.max(1, w))
                + (discussPost.getCreateTime().getTime() - EPOCH.getTime()) / (1000 * 3600 * 24);

        // 更新帖子分数
        discussPostService.updateScoreById(postId, score);
        discussPost.setScore(score);
        // 同步搜索数据
        elasticsearchService.saveDiscussPost(discussPost);

    }
}
